package net.mcg_server.jbi.xml;

import java.io.File;
import java.util.ArrayList;

import javax.swing.JFileChooser;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import net.mcg_server.jbi.Program;
import net.mcg_server.jbi.data.Game;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class XMLWriter {

	private DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
	private DocumentBuilder dBuilder;
	private StreamResult file;
	private String loc;

	public XMLWriter(){
	}

	public String writeXml(final Program program){

		try{
			
			//System.out.println("Building XML document");
			
			dBuilder = dbFactory.newDocumentBuilder();
			Document doc = dBuilder.newDocument();

			Element rootElement = doc.createElementNS("gamelist", "gamelist");
			doc.appendChild(rootElement);

			for(int i = 0; i < program.getGameList().size(); i++){
				rootElement.appendChild(getGame(program, doc, i));
			}
			
			// http://www.journaldev.com/1112/how-to-write-xml-file-in-java-dom-parser
			// for the rest of the code
			TransformerFactory transformerFactory = TransformerFactory.newInstance();
			Transformer xformer = transformerFactory.newTransformer();
			xformer.setOutputProperty(OutputKeys.INDENT, "yes");
			DOMSource source = new DOMSource(doc);
			
			JFileChooser fileChooser = new JFileChooser(System.getProperty("user.home")+"/Documents/JBI/GameLists");
			fileChooser.setMultiSelectionEnabled(false);
			
			FileFilter xmlFilter = new FileNameExtensionFilter("XML File", "xml");
			fileChooser.setFileFilter(xmlFilter);
			
			int value = fileChooser.showSaveDialog(null);
			if(value == JFileChooser.APPROVE_OPTION){
				try{
					FileFilter selected = fileChooser.getFileFilter();
					String ext = "";
					
					File outFile;
					if(!fileChooser.getSelectedFile().toString().contains(".xml")){
						if(selected == xmlFilter){
							ext = ".xml";
						}
						outFile = new File(fileChooser.getSelectedFile()+ext);
						
					}else{
						if(selected == xmlFilter){
							ext = "";
						}
						outFile = fileChooser.getSelectedFile();
					}
					
					loc = outFile.toString();
					file = new StreamResult(outFile);
				}catch(Exception e){
					e.printStackTrace();
				}
			}
			
			xformer.transform(source, file);
			
		}catch(Exception e){

		}
		
		return loc;
	}

	public static Element getGame(Program program, Document doc, int i){
		Element game = doc.createElement("game");

		game.appendChild(getGameTitle(program, doc, i));
		game.appendChild(getGameDescription(program, doc, i));
		game.appendChild(getBeatenStatus(program, doc, i));

		return game;
	}

	public static Element getGameTitle(Program program, Document doc, int i){
		Element gameTitle = doc.createElement("title");

		ArrayList<Game> gameList = program.getGameList();
		Game game = gameList.get(i);

		gameTitle.appendChild(doc.createTextNode(game.getTitle()));

		return gameTitle;
	}

	public static Element getGameDescription(Program program, Document doc, int i){
		Element gameDescription = doc.createElement("description");

		ArrayList<Game> gameList = program.getGameList();
		Game game = gameList.get(i);

		gameDescription.appendChild(doc.createTextNode(game.getDescription()));

		return gameDescription;
	}

	public static Element getBeatenStatus(Program program, Document doc, int i){
		Element isBeaten = doc.createElement("isBeaten");

		ArrayList<Game> gameList = program.getGameList();
		Game game = gameList.get(i);

		String str;
		if(game.isBeaten()==true){
			str = "true";
		}else{
			str = "false";
		}

		isBeaten.appendChild(doc.createTextNode(str));

		return isBeaten;
	}

}
